# -*- coding: utf-8 -*-

import sqlite3
import time
import hashlib

error = {
    -401: {
        "code": -401,
        "message": "初始化失败(传递参数 force来强制初始化)"},
    -101: {
        "code": -101,
        "message": "用户名不存在"
    },
    -102: {
        "code": -102,
        "message": "密码错误"
    },
    -201: {
        "code": -201,
        "message": "请先登录"
    },
    -202: {
        "code": -202,
        "message": "key过期,请重新登陆"
    },
    -203: {
        "code": -203,
        "message": "权限不足"
    },
    -301: {
        "code": -301,
        "message": "文章不存在"
    }
}

app = None
updata_root = ""

def init(flask_app):
    global app, updata_root
    app = flask_app

def connect_db():
    con = sqlite3.connect("data.db")
    return con

def init_blog(flask_app, admin, pwd, force=False):
    global app
    app = flask_app
    with app.app_context():
        con = connect_db()
        if force:
            con.cursor().execute("DROP TABLE 'articles';")
            con.commit()
            con.cursor().execute("DROP TABLE 'user';")
            con.commit()
            con.cursor().execute("DROP TABLE auth;")
            con.commit()
        try:
            con.cursor().execute("CREATE TABLE 'articles' ('id' INT PRIMARY KEY, 'title' TEXT, 'date' TEXT, 'summary' TEXT, 'context' TEXT, 'view' INT);")
            con.commit()
            con.cursor().execute("CREATE TABLE 'user' ('username' TEXT PRIMARY KEY, 'password' TEXT, 'admin' INT);")
            con.commit()
            con.cursor().execute("INSERT INTO 'user' VALUES(?, ?, 0)", (admin, pwd))
            con.commit()
            con.cursor().execute("CREATE TABLE auth ('username' TEXT PRIMARY KEY, 'key' TEXT, 'expires' INT, 'admin' INT);")
            con.commit()
        except sqlite3.OperationalError:
            return error[-401]
        return {
            "code": 0,
            "username": admin,
            "password": pwd
        }

def login(username, pwd):
    with app.app_context():
        con = connect_db()
        user = con.cursor().execute("SELECT * FROM user WHERE username = ?", (username, )).fetchone()
        if user:
            if pwd == user[1]:
                key = hashlib.md5((user[0] + user[1] + str(time.time()) + "girigirilove").encode("utf-8")).hexdigest()
                expires = int(time.time()) + 3600
                try:
                    con.cursor().execute("INSERT INTO auth VALUES (?, ?, ?, ?)", (user[0], key, expires, user[2]))
                except sqlite3.IntegrityError:
                    con.cursor().execute("UPDATE auth SET key = ? WHERE username = ?", (key, user[0]))
                con.commit()
                return {
                    "code": 0,
                    "username": user[0],
                    "key": key,
                    "admin": user[2],
                    "expires": expires
                }
            else:
                return error[-102]
        else:
            return error[-101]

def check_key(key, con=None):
    with app.app_context():
        if not con:
            con = sqlite3.connect("data.db")
        user = con.cursor().execute("SELECT * FROM auth WHERE key = ?", (key, )).fetchone()
        if user:
            if user[2] > int(time.time()):
                return user[0], user[3]
            else:
                con.cursor().execute("DELETE FROM auth WHERE username = ?", (user[0], ))
                con.commit()
                return False
        else:
            return None

def article_list(page=1, page_size=20):
    with app.app_context():
        con = connect_db()
        
        total_count = con.cursor().execute("SELECT COUNT(*) FROM 'articles'").fetchone()[0]
        if total_count < page_size:
            total_page = 1
        else:
            total_page = total_count // page_size 
            if total_count % page_size != 0:
                total_page + 1
        id_start = page_size * (page - 1) 
        id_end = page_size * page - 1
        if id_end > total_count:
            id_end = total_count + 1
        articles = [ {"article_id": i[0], "title": i[1], "date": i[2], "summary": i[3], "view": i[4]} for i in con.cursor().execute("SELECT id, title, date, summary, view FROM articles WHERE id BETWEEN ? AND ?", (id_start, id_end)).fetchall() ]
        return {
            "code": 0,
            "total_count": total_count,
            "total_page": total_page,
            "results": articles
        }

def article_post(data, key):
    with app.app_context():
        con = connect_db()
        username, admin = check_key(key, con)
        if username:
            if admin >= 0:
                last_id = con.cursor().execute("SELECT id FROM articles ORDER BY id DESC").fetchone()
                if not last_id:
                    article_id = 0
                else:
                    article_id = last_id[0] + 1
                
                if len(data["context"]) < 100:
                    summary = data["context"]
                else:
                    summary = data["context"][0:100]
                data = (
                    article_id,
                    data["title"],
                    time.strftime("%Y-%m-%d %H:%M:%S"),
                    summary,
                    data["context"],
                    0
                )
                con.cursor().execute("INSERT INTO articles VALUES (?, ?, ?, ?, ?, ?)", data)
                con.commit()
                return {
                    "code": 0,
                    "article_id": article_id
                }
            else:
                return error[-203]
        elif username is None:
            return error[-201]
        elif username is False:
            return error[-202]

def article_delete(article_id, key):
    with app.app_context():
        con = connect_db()
        username, admin = check_key(key, con)
        if username:
            if admin >= 0:
                if con.cursor().execute("SELECT COUNT(*) FROM articles WHERE id=?", (article_id, )).fetchone()[0] == 0:
                    return error[-301]
                else:
                    con.cursor().execute("DELETE FROM articles WHERE id=?", (article_id, ))
                    con.commit()
                    return {
                        "code": 0,
                        "article_id": article_id
                    }
            else:
                return error[-203]
        elif username is None:
            return error[-201]
        elif username is False:
            return error[-202]

def article_detail(article_id):
    with app.app_context():
        con = connect_db()
        article = con.cursor().execute("SELECT id, title, date, context, view FROM articles WHERE id=?", (article_id,)).fetchone()
        if not article:
            return error[-301]
        else:
            return {
                "code": 0,
                "result": dict(
                    zip(("article_id", "title", "date", "context", "view"),
                        article))
            }
